package org.elec.mac.utils;
import java.util.Locale;


/**
 * 有关价格的. 价格统一使用一个 long 变量表示, 单位‘1e-2元’
 */
public final class PriceUtil {

    /**
     * 表示未知价格
     */
    public static final long UNKNOWN = -0x8000_0000;

    public static final String TEXT_UNKNOWN = "(Unknown)";

    /**
     * 从字符串中解除出价格. 比如 "9", "9.5", "8.99" 等
     * <p/>
     *
     * 返回一个以单位‘1e-2元’来表示的价格, 如果传入的字符串有4位以上的小数,
     * 则4舍5入.
     *
     * @throws NumberFormatException 如果解析失败
     */
    public static long parse(String text) {
        if(text.isEmpty()) {
            throw new NumberFormatException("无法解析成价格: " + text);
        }

        if(TEXT_UNKNOWN.equals(text)) {
            return UNKNOWN;
        }

        boolean isNegative = text.charAt(0) == '-';
        if(isNegative) {
            // skip '-'
            text = text.substring(1);
        }

        String[] values = text.split("\\.", -2);

        if (1 == values.length) {
            // 没有小数点
            long price = 100 * Long.valueOf(values[0]);

            return isNegative ? -price : price;
        }

        if (2 != values.length) {
            throw new NumberFormatException("无法解析成价格: " + text);
        }

        long price = 100 * Long.valueOf(values[0]);
        int decimalLength = values[1].length();
        long decimalPart = Long.valueOf(values[1]);

        for (int i = 0; i < 2 - decimalLength; i++) {
            decimalPart *= 10;
        }

        while (decimalPart >= 1000) {
            decimalPart /= 10;
        }
        if (decimalPart > 100) {
            decimalPart += 5;
            decimalPart /= 10;
        }

        price += decimalPart;

        return isNegative ? -price : price;
    }

    /**
     * 返回一个表示价格的字符串, 统一保留 2 位小数
     */
    public static String toPriceString(long price) {
        if(UNKNOWN == price) {
            return TEXT_UNKNOWN;
        }

        boolean isNegative = price < 0;
        if(isNegative) {
            price = -price;
        }
        String text = String.format(Locale.getDefault(), "%1$d.%2$02d", price / 100, price % 100);
        return isNegative ? "-" + text : text;
    }
}
